<script setup lang="ts">
import { ref, computed } from 'vue'
import { onLoad, onReachBottom } from '@dcloudio/uni-app'
import { getComplaint, deleteComplaint } from '@/api/complaint'
import { pageQuery, agree, detail, pageByAncestor, comment, del } from '@/api/comment'
import { upload } from '@/api/file'
import type { Complaint } from '@/api/complaint/type'
import type { Comment } from '@/api/comment/type'
import { toast } from '@/utils/common'
import { BaseResponse } from '@/api/base'
import store from '@/store'
import { optAgree, optDisAgree } from './common'

const complaintId = ref()
const complaint = ref<Complaint>({})
const commentList = ref<Comment[]>([])
const commentIndex = ref<number>(0)
const popTarget = ref<string>('parent')
const loadStatus = ref<string>('loadmore')
const moreStatus = ref<boolean>(true)
const loadingText = ref<string>('加载中')
const loadmoreText = ref<string>('加载更多')
const nomoreText = ref<string>('已显示全部评论')
const subLoadStatus = ref<string[]>([])
const subMoreStatus = ref<boolean[]>([])
const subLoadingText = ref<string>('加载中')
const subLoadmoreText = ref<string>('展开更多回复')
const pageReq = ref({
  pageNum: 1,
  pageSize: 5,
  total: 0
})
const commentReq = ref({
  ancestor: '',
  pageNum: 2,
  pageSize: 3,
  total: 0
})
const tabsList = ref([{
  name: '最新',
  value: 'new'
},
{
  name: '最热',
  value: 'hot'
}
])
const tap = ref<string>('new')
const commentPop = ref()
const popUpPlaceHolder = ref<string>('添加评论')
const commentForm = ref({
  pId: 0,
  complaintId: 0,
  ancestor: 0,
  content: '',
  pNickname: '',
  pic: '',
  picObj: {}
})
const optActions = ref([
  {
    name: '点赞',
    color: '#000000'
  },
  {
    name: '评论',
    color: '#000000'
  }
])
const actionSheet = ref()
const currentComment = ref<Comment>()
const popData = ref([{ title: '删除' }])
const bubbleMenuShow = ref<boolean>()
const x = ref<number>(0)
const y = ref<number>(0)
const currentData = ref<Complaint>()

const loadComplaint = async () => {
  try {
    const res: BaseResponse = await getComplaint(complaintId.value)
    complaint.value = res.data
  } catch (error) {
    toast(error.tips)
  }
}
const loadComment = async (order: string) => {
  try {
    loadStatus.value = 'loading'
    const req = { order: order, complaintId: complaintId.value, pageNum: pageReq.value.pageNum, pageSize: pageReq.value.pageSize }
    const res: BaseResponse = await pageQuery(req)
    res.data.records.forEach(async (item: Comment) => {
      if (!item.children || item.subCommentsTotal <= item.children.length) {
        subLoadStatus.value.push('nomore')
        subMoreStatus.value.push(false)
      } else {
        subLoadStatus.value.push('loadmore')
        subMoreStatus.value.push(true)
      }
    })
    if (res.data.records.length < pageReq.value.pageSize) {
      loadStatus.value = 'nomore'
      moreStatus.value = false
      commentList.value = commentList.value.concat(res.data.records)
      pageReq.value.total = res.data.total
      return
    }
    if (!res.data || res.data.records.length == 0 || res.data.total <= commentList.value.length) {
      loadStatus.value = 'nomore'
      moreStatus.value = false
      pageReq.value.total = res.data.total
      return
    }
    commentList.value = commentList.value.concat(res.data.records)
    loadStatus.value = 'loadmore'
    pageReq.value.pageNum++
    pageReq.value.total = res.data.total
  } catch (error) {
    loadStatus.value = 'nomore'
    moreStatus.value = false
    toast(error.tips)
  }
}
const loadCommentDetail = async (item: Comment) => {
  try {
    const res: BaseResponse = await detail(item.id)
    item.agree = res.data.agree
    item.agreeCount = res.data.agreeCount
  } catch (error) {
    toast(error.tips)
  }
}
const loadSubComment = async (item: Comment, index: number) => {
  if (!subMoreStatus.value[index]) {
    return
  }
  try {
    const req = { ancestor: item.id, pageNum: commentReq.value.pageNum, pageSize: commentReq.value.pageSize }
    const res: BaseResponse = await pageByAncestor(req)
    if (res.data.records.length < commentReq.value.pageSize) {
      subLoadStatus.value[index] = 'nomore'
      subMoreStatus.value[index] = false
      if (res.data.records.length == 0) {
        return
      }
      commentList.value[index].children = commentList.value[index].children.concat(res.data.records)
      commentReq.value.total = res.data.total
      return
    }
    if (commentReq.value.pageNum >= res.data.pages) {
      subLoadStatus.value[index] = 'nomore'
      subMoreStatus.value[index] = false
    }
    commentList.value[index].children = commentList.value[index].children.concat(res.data.records)
    commentReq.value.pageNum++
    commentReq.value.total = res.data.total
  } catch (error) {
    toast(error.tips)
  }
}
const delComment = async (item: Comment) => {
  try {
    await del(item.id)
    toast('删除成功')
    commentList.value.splice(commentList.value.indexOf(item), 1)
    pageReq.value.total--
  } catch (error) {
    toast(error.tips)
  }
}

const delComplaint = async (item: Complaint) => {
  await deleteComplaint(item.id)
}

onLoad((option: any) => {
  complaintId.value = option.id
  loadComplaint()
  loadComment(tap.value)
})
onReachBottom(() => {
  // 如果依然还有数据，就触发
  if (moreStatus.value == true) {
    loadStatus.value = 'loading'
    setTimeout(() => {
      loadComment(tap.value)
      loadStatus.value = 'loadmore'
    }, 500)
  }
})
const getSize = computed(() => {
  const v = uni.upx2px(750) - 40
  const w = v / 3
  return {
    width: w + 'px',
    height: w + 'px'
  }
})
const query = (e: any) => {
  tap.value = e.value
  commentList.value = []
  loadComment(e.value)
  subLoadStatus.value = []
  subMoreStatus.value = []
}
const optCommentAgree = async (item: any) => {
  try {
    await agree(item.id)
    loadCommentDetail(item)
  } catch (error) {
    toast(error.tips)
  }
}
const showCommentPop = (target: string, item: Comment, index: number) => {
  commentPop.value?.open()
  popUpPlaceHolder.value = '回复 ' + item.nickname
  commentIndex.value = index
  popTarget.value = target
  commentForm.value.pId = item.id
  commentForm.value.pNickname = item.nickname
  commentForm.value.ancestor = item.ancestor
  commentForm.value.content = ''
  commentForm.value.pic = ''
  commentForm.value.picObj = {}
}
const showComplaintPop = () => {
  commentPop.value?.open()
  popUpPlaceHolder.value = '添加评论'
  popTarget.value = 'grant'
  commentForm.value.content = ''
  commentForm.value.pic = ''
  commentForm.value.picObj = {}
}
const choosePic = () => {
  uni.chooseImage({
    count: 1,
    sizeType: ['compressed'],
    sourceType: ['album', 'camera'],
    success: async (res: any) => {
      const file = res.tempFiles[0]
      const uploadRes = await upload(file.path, file.name)
      commentForm.value.picObj = {
        status: 'success',
        message: '',
        url: uploadRes.data.actionUrl
      }
      commentForm.value.pic = uploadRes.data.actionUrl.substring(uploadRes.data.actionUrl.lastIndexOf('files') - 1)
    }
  })
}
const deletePic = () => {
  commentForm.value.pic = ''
  commentForm.value.picObj = {}
}
const sendComment = async () => {
  if (!commentForm.value.content) {
    toast('请输入评论内容')
    return
  }
  try {
    if (popTarget.value === 'grant') {
      commentForm.value.complaintId = complaintId.value
      commentForm.value.pId = 0
      commentForm.value.ancestor = 0
      const res = await comment(commentForm.value)
      commentList.value.unshift(res.data)
    } else {
      if (popTarget.value === 'parent') {
        commentForm.value.ancestor = commentForm.value.pId
      } else if (popTarget.value === 'child') {
        commentForm.value.ancestor = commentForm.value.ancestor
      }
      commentForm.value.complaintId = complaintId.value
      const res = await comment(commentForm.value)
      const temp = commentList.value[commentIndex.value]
      if (!temp.children) {
        temp.children = []
      }
      temp.children.unshift(res.data)
      commentList.value[commentIndex] = temp
      temp.commentCount++
    }
    pageReq.value.total++
    commentPop.value?.close()
    toast("评论成功")
  } catch (error) {
    toast(error.tips)
  }
}

const showOptPop = (target: string, item: Comment, index: number) => {
  commentIndex.value = index
  popTarget.value = target
  currentComment.value = item
  if (store.getters.id === item.userId) {
    optActions.value = [
      {
        name: '点赞',
        color: '#000000'
      },
      {
        name: '评论',
        color: '#000000'
      },
      {
        name: '删除',
        color: '#000000'
      }
    ]
  } else {
    optActions.value = [
      {
        name: '点赞',
        color: '#000000'
      },
      {
        name: '评论',
        color: '#000000'
      }
    ]
  }
  actionSheet.value?.open()
}

const selectOpt = (item: any) => {
  if (item.name === '点赞') {
    optCommentAgree(currentComment.value)
  } else if (item.name === '评论') {
    showCommentPop(popTarget.value, currentComment.value, commentIndex.value)
  } else if (item.name === '删除') {
    delComment(currentComment.value)
  }
}

const showBubbleMenu = (item: Complaint, event: any) => {
  x.value = event.touches[0].clientX
  y.value = event.touches[0].clientY + 5
  bubbleMenuShow.value = !bubbleMenuShow.value
  currentData.value = item
}
const tapPopup = async (i: any) => {
  if (i.title === '删除') {
    try {
      delComplaint(currentData.value)
      toast('删除成功')
      uni.navigateBack()
      uni.$emit('backRefresh')
    } catch (error) {
      toast(error.tips)
    }
  }
}
</script>

<template>
  <view class="complaint-detail">
    <view class="complaint-area">
      <user-info class="complaint-area-userinfo" :data="complaint">
        <uv-icon v-show="store.getters.id === complaint.userId" name="more-dot-fill"
          @click="showBubbleMenu(complaint, $event)"></uv-icon>
      </user-info>
      <view class="complaint-area-text">
        <uv-text :text="complaint.content"></uv-text>
      </view>
      <uv-grid v-show="complaint.pic" class="complaint-area-pic" :border="false">
        <uv-grid-item v-for="(p, index) in complaint.pic?.split(',')" :key="index" style="margin-bottom: 10rpx;">
          <my-image :customStyle="getSize" :index="index" :src="p"></my-image>
        </uv-grid-item>
      </uv-grid>
    </view>
    <view class="comment-area">
      <view class="comment-area-top">
        <uv-text :text="'评论 ' + pageReq.total"></uv-text>
        <uv-tabs v-show="false" :list="tabsList" @click="query"></uv-tabs>
      </view>
      <view class="comment-area-content">
        <view class="comment-area-content-item" v-for="(item, index) in commentList" :key="index">
          <view class="userinfo-left">
            <my-avatar class="userinfo-avatar" :src="item.avatar"></my-avatar>
          </view>
          <view class="userinfo-right">
            <view style="display: flex;">
              <uv-text style="width: auto;flex: unset;" size="28rpx" color="#999" lineHeight="40rpx"
                :text="item.nickname"></uv-text>
              <uv-tags style="width: auto;flex: unset;margin-left: 10rpx;" :border="false" size="mini" plain plainFill
                v-show="complaint.userId === item.userId" text="作者"></uv-tags>
            </view>
            <uv-text style="margin-bottom: 10rpx;" :text="item.content"></uv-text>
            <my-image v-show="item.pic" :customStyle="{ 'margin-bottom': '10rpx', width: '300rpx', height: '300rpx' }"
              :src="item.pic"></my-image>
            <view class="userinfo-bottom">
              <uv-text class="userinfo-timeAgo" style="width: 50%;" size="24rpx" color="#999"
                :text="item.timeAgo"></uv-text>
              <view class="userinfo-opt">
                <view class="userinfo-opt-item" @click="showOptPop('parent', item, index)">
                  <uv-icon class="opt-item-text" name="more-dot-fill">
                  </uv-icon>
                </view>
                <view class="userinfo-opt-item" @click="showCommentPop('parent', item, index)">
                  <uv-text class="opt-item-text" :color="item.comment ? '#1e80ff' : '#999'" size="24rpx"
                    :iconStyle="{ 'font-size': '35rpx', 'color': item.comment ? '#1e80ff' : '#999' }"
                    :prefixIcon="item.comment ? 'chat-fill' : 'chat'"
                    :text="item.commentCount ? item.commentCount : ''"></uv-text>
                </view>
                <view class="userinfo-opt-item" @click="optCommentAgree(item)">
                  <uv-text class="opt-item-text" :color="item.agree ? '#1e80ff' : '#999'" size="24rpx"
                    :iconStyle="{ 'font-size': '35rpx', 'color': item.agree ? '#1e80ff' : '#999' }"
                    :prefixIcon="item.agree ? 'thumb-up-fill' : 'thumb-up'"
                    :text="item.agree ? item.agreeCount : ''"></uv-text>
                </view>
              </view>
            </view>
            <view class="children" v-show="item.children && item.children.length > 0">
              <view class="children-item" v-for="(sub, i) in item.children" :key="i">
                <view class="children-userinfo-left">
                  <my-avatar :customStyle="{ width: '50rpx', height: '50rpx' }" class="children-userinfo-avatar"
                    :src="sub.avatar"></my-avatar>
                </view>
                <view class="children-userinfo-right">
                  <view class="children-userinfo-text">
                    <view style="font-size: 28rpx; color: #999;line-height: 40rpx;display: inline;">{{
                      sub.nickname }}</view>
                    <view class="children-userinfo-tags" v-show="complaint.userId === sub.userId">作者</view>
                    <view v-show="sub.pNickname && sub.pId !== 0 && sub.ancestor != 0"
                      style="display: inline;margin-left: 10rpx;">
                      <view style=" display: inline;font-size: 28rpx; line-height: 40rpx;">回复</view>
                      <view
                        style="display: inline;font-size: 28rpx; color: #999;line-height: 40rpx;margin-left: 10rpx;">
                        {{ sub.pNickname }}</view>
                    </view>
                    <view style="font-size: 28rpx; line-height: 40rpx;display: inline;">{{ '：' + sub.content }}
                    </view>
                  </view>
                  <my-image v-show="sub.pic"
                    :customStyle="{ 'margin-bottom': '10rpx', width: '50rpx', height: '50rpx' }"
                    :src="sub.pic"></my-image>
                  <view class="children-userinfo-bottom">
                    <uv-text class="children-userinfo-timeAgo" size="24rpx" color="#999" :text="sub.timeAgo"></uv-text>
                    <view class="children-userinfo-opt">
                      <view class="children-userinfo-opt-item" @click="showOptPop('child', sub, index)">
                        <uv-icon class="children-opt-item-text" name="more-dot-fill">
                        </uv-icon>
                      </view>
                      <view class="children-userinfo-opt-item" @click="showCommentPop('child', sub, index)">
                        <uv-text class="children-opt-item-text" :color="sub.comment ? '#1e80ff' : '#999'" size="24rpx"
                          :iconStyle="{ 'font-size': '35rpx', 'color': sub.comment ? '#1e80ff' : '#999' }"
                          :prefixIcon="sub.comment ? 'chat-fill' : 'chat'"
                          :text="sub.commentCount ? sub.commentCount : ''"></uv-text>
                      </view>
                      <view class="children-userinfo-opt-item" @click="optCommentAgree(sub)">
                        <uv-text class="children-opt-item-text" :color="sub.agree ? '#1e80ff' : '#999'" size="24rpx"
                          :iconStyle="{ 'font-size': '35rpx', 'color': sub.agree ? '#1e80ff' : '#999' }"
                          :prefixIcon="sub.agree ? 'thumb-up-fill' : 'thumb-up'"
                          :text="sub.agree ? sub.agreeCount : ''"></uv-text>
                      </view>
                    </view>
                  </view>
                </view>
              </view>
              <uv-load-more bgColor="#fff" :status="subLoadStatus[index]" @loadmore="loadSubComment(item, index)"
                :loading-text="subLoadingText[index]" nomoreText="" :loadmore-text="subLoadmoreText"></uv-load-more>
            </view>
          </view>
        </view>
      </view>
      <view style="padding-top:10px;background-color: #fff;">
        <uv-load-more bgColor="#fff" :status="loadStatus" line lineColor="#f1f1f1" :dashed="false"
          @loadmore="loadComment" :loading-text="loadingText" :loadmore-text="loadmoreText"
          :nomore-text="nomoreText"></uv-load-more>
      </view>
    </view>
    <uv-line></uv-line>
    <view class="complaint-detail-opt">
      <view class="complaint-detail-opt-input" @click="showComplaintPop">
        <uv-input shape="circle" placeholder="请输入评论" disabled v-model="commentForm.content"></uv-input>
      </view>
      <view class="complaint-detail-opt-item" @click="optAgree(complaint)">
        <uv-text class="complaint-detail-opt-item-text" :color="complaint.agree ? '#1e80ff' : '#999'" size="28rpx"
          lineHeight="50rpx" :iconStyle="{ 'font-size': '40rpx', 'color': complaint.agree ? '#1e80ff' : '#999' }"
          :prefixIcon="complaint.agree ? 'thumb-up-fill' : 'thumb-up'"
          :text="complaint.agreeCount ? complaint.agreeCount : ''"></uv-text>
      </view>
      <view class="complaint-detail-opt-item" @click="optDisAgree(complaint)">
        <uv-text class="complaint-detail-opt-item-text" :color="complaint.reject ? '#1e80ff' : '#999'" size="28rpx"
          lineHeight="50rpx" :iconStyle="{ 'font-size': '40rpx', 'color': complaint.reject ? '#1e80ff' : '#999' }"
          :prefixIcon="complaint.reject ? 'thumb-down-fill' : 'thumb-down'"
          :text="complaint.rejectCount ? complaint.rejectCount : ''"></uv-text>
      </view>
    </view>
    <uv-popup ref="commentPop" mode="bottom">
      <uv-form :model="commentForm" class="comment-form">
        <uv-form-item prop="content">
          <uv-textarea :placeholder="popUpPlaceHolder" v-model="commentForm.content" count autoHeight
            maxlength="200"></uv-textarea>
        </uv-form-item>
        <view style="display: flex;justify-content: space-between;">
          <view style="display: flex;">
            <uv-icon name="photo-fill" @click="choosePic" size="60rpx"></uv-icon>
            <uv-upload v-show="commentForm.pic" :showSuccessIcon="false" width="80rpx" height="80rpx"
              :fileList="[commentForm.picObj]" name="pic" :maxCount="1" @delete="deletePic"></uv-upload>
          </view>
          <uv-button text="发送" type="primary" shape="circle" :customStyle="{ height: '60rpx' }"
            :disabled="!commentForm.content" @click="sendComment"></uv-button>
        </view>
      </uv-form>
    </uv-popup>
    <uv-action-sheet ref="actionSheet" :actions="optActions" @select="selectOpt">
    </uv-action-sheet>
    <bubble-menu v-model="bubbleMenuShow" :popData="popData" @tapPopup="tapPopup" :x="x" :y="y" placement="top-end">
    </bubble-menu>
  </view>
</template>

<style lang="scss" scoped>
.complaint-area {
  background-color: #fff;
  padding: 20rpx 20rpx 10rpx 20rpx;
  margin-bottom: 10rpx;

  &-userinfo {
    margin-bottom: 10rpx;
  }

  &-text {
    margin-bottom: 10rpx;
  }
}

.comment-area {
  padding: 10rpx 20rpx;
  background-color: #fff;

  &-top {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 10rpx;
  }

  &-content-item {
    display: flex;
    justify-content: left;
    flex-direction: row;
    margin-bottom: 20rpx;
  }

  .userinfo-right {
    display: flex;
    flex-direction: column;
    margin-left: 20rpx;
    width: calc(100% - 100rpx);

    .userinfo-bottom {
      display: flex;
      flex-direction: row;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 20rpx;

      .userinfo-opt {
        display: flex;
        width: 40%;
        flex-direction: row;
        align-items: center;

        .userinfo-opt-item {
          display: flex;
          flex-direction: row;
          align-items: center;
          justify-content: center;
          flex: 1;

          .opt-item-text {
            justify-content: center !important;
          }
        }
      }
    }

    .children-item {
      display: flex;
      justify-content: left;
      flex-direction: row;
      margin-bottom: 20rpx;

      .children-userinfo-right {
        display: flex;
        flex-direction: column;
        margin-left: 20rpx;
        flex: 1;
        width: calc(100% - 100rpx);

        .children-userinfo-text {
          margin-bottom: 10rpx;

          .children-userinfo-tags {
            margin-left: 10rpx;
            display: inline;
            font-size: 24rpx;
            padding: 0 5rpx;
            line-height: 60rpx;
            background-color: #ecf5ff;
            color: #3c9cff;
          }
        }

        .children-userinfo-bottom {
          display: flex;
          flex-direction: row;
          justify-content: space-between;
          align-items: center;

          .children-userinfo-opt {
            display: flex;
            flex-direction: row;
            align-items: center;
            width: 45%;

            .children-userinfo-opt-item {
              display: flex;
              flex-direction: row;
              align-items: center;
              justify-content: center;
              flex: 1;

              .children-opt-item-text {
                justify-content: center !important;
              }
            }
          }
        }
      }
    }
  }
}

.complaint-detail-opt {
  display: flex;
  position: fixed;
  bottom: 0;
  width: calc(100% - 40rpx);
  flex-direction: row;
  padding: 10rpx 20rpx;
  background-color: #fff;
  align-items: center;

  &-input {
    width: 50%;
    display: flex;
    align-items: center;
  }

  &-item {
    width: 25%;
    display: flex;
    align-items: center;

    &-text {
      justify-content: center !important;
    }
  }
}

.comment-form {
  padding: 10rpx 20rpx;
}
</style>
